package com.example.project.service.impl;

import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.example.project.constant.I18n;
import com.example.project.core.text.Convert;
import com.example.project.entity.Attachment;
import com.example.project.entity.Issue;
import com.example.project.entity.IssueCategorie;
import com.example.project.entity.IssuePrioritie;
import com.example.project.entity.IssueRelation;
import com.example.project.entity.IssueStatus;
import com.example.project.entity.JournalDetail;
import com.example.project.entity.Project;
import com.example.project.entity.Tracker;
import com.example.project.entity.User;
import com.example.project.enums.IssueRelationType;
import com.example.project.mapper.IssueMapper;
import com.example.project.mapper.JournalDetailMapper;
import com.example.project.service.AttachmentService;
import com.example.project.service.CommonService;
import com.example.project.service.JournalDetailService;
import com.example.project.service.UserService;
import com.example.project.utils.DateUtils;
import com.example.project.utils.StringUtils;

/**
 * 变更详情，存储journal记录的详细变更信息Service业务层处理
 * 
 * @author ruoyi
 * @date 2025-09-26
 */
@Service
public class JournalDetailServiceImpl implements JournalDetailService {

	@Autowired
	private IssueMapper issueMapper;

	@Autowired
	private JournalDetailMapper journalDetailMapper;

	@Autowired
	private CommonService commonService;

	@Autowired
	private UserService userService;

	@Autowired
	private AttachmentService attachmentService;

	/**
	 * 查询变更详情，存储journal记录的详细变更信息
	 * 
	 * @param id 变更详情，存储journal记录的详细变更信息主键
	 * @return 变更详情，存储journal记录的详细变更信息
	 */
	@Override
	public JournalDetail selectJournalDetailsById(Long id) {
		return journalDetailMapper.selectJournalDetailsById(id);
	}

	/**
	 * 查询变更详情，存储journal记录的详细变更信息列表
	 * 
	 * @param tJournalDetails 变更详情，存储journal记录的详细变更信息
	 * @return 变更详情，存储journal记录的详细变更信息
	 */
	@Override
	public List<JournalDetail> selectJournalDetailsList(JournalDetail tJournalDetails) {
		return journalDetailMapper.selectJournalDetailsList(tJournalDetails);
	}

	/**
	 * 新增变更详情，存储journal记录的详细变更信息
	 * 
	 * @param tJournalDetails 变更详情，存储journal记录的详细变更信息
	 * @return 结果
	 */
	@Override
	public int insertJournalDetails(JournalDetail tJournalDetails) {
		return journalDetailMapper.insertJournalDetails(tJournalDetails);
	}

	/**
	 * 修改变更详情，存储journal记录的详细变更信息
	 * 
	 * @param tJournalDetails 变更详情，存储journal记录的详细变更信息
	 * @return 结果
	 */
	@Override
	public int updateJournalDetails(JournalDetail tJournalDetails) {
		return journalDetailMapper.updateJournalDetails(tJournalDetails);
	}

	/**
	 * 批量删除变更详情，存储journal记录的详细变更信息
	 * 
	 * @param ids 需要删除的变更详情，存储journal记录的详细变更信息主键
	 * @return 结果
	 */
	@Override
	public int deleteJournalDetailsByIds(String ids) {
		return journalDetailMapper.deleteJournalDetailsByIds(Convert.toStrArray(ids));
	}

	/**
	 * 删除变更详情，存储journal记录的详细变更信息信息
	 * 
	 * @param id 变更详情，存储journal记录的详细变更信息主键
	 * @return 结果
	 */
	@Override
	public int deleteJournalDetailsById(Long id) {
		return journalDetailMapper.deleteJournalDetailsById(id);
	}

	@Override
	public List<JournalDetail> findListByJournalId(long journalId) {
		// TODO Auto-generated method stub
		List<JournalDetail> detailList = journalDetailMapper.selectListByJournalId(journalId);

		return detailList;
	}

	/**
	 * 返回单个日志详情的文本表示 对应 Ruby 的 show_detail 方法
	 */
	@Override
	public String showDetail(JournalDetail detail) {
		boolean multiple = false;
		boolean showDiff = false;
		boolean noDetails = false;

		String label = StringUtils.isEmpty(detail.getDescription()) ? "" : detail.getDescription();
		String value = detail.getValue();
		String oldValue = detail.getOldValue();

		Map<Long, Tracker> trackerMap = commonService.getTrackerMap();

		switch (detail.getProperty()) {
		case "attr": {
			String field = detail.getPropKey();
			// 判断：根据属性键处理不同类型的属性
			switch (field) {
			case "projectId":
			case "statusId":
			case "trackerId":
			case "assignedToId":
			case "priorityId":
			case "categoryId":
			case "fixedVersionId":
				// 判断：处理关联ID类型的属性，通过反射查找名称
				value = findNameByReflection(field, detail.getValue());
				oldValue = findNameByReflection(field, detail.getOldValue());
				break;

			case "estimatedHours":
				// 判断：如果新值不为空且非空字符串，格式化小时数
				if (StringUtils.isNotEmpty(detail.getValue())) {
					value = DateUtils.formatEstimatedHours(detail.getValue());
				}
				// 判断：如果旧值不为空且非空字符串，格式化小时数
				if (StringUtils.isNotEmpty(detail.getOldValue())) {
					oldValue = DateUtils.formatEstimatedHours(detail.getOldValue());
				}
				break;

			case "parentId":
				label = I18n.t("field_parent_issue");
				// 判断：如果新值不为空且非空字符串，添加#前缀
				if (StringUtils.isNotEmpty(detail.getValue())) {
					value = "#" + detail.getValue();
				}
				// 判断：如果旧值不为空且非空字符串，添加#前缀
				if (StringUtils.isNotEmpty(detail.getOldValue())) {
					oldValue = "#" + detail.getOldValue();
				}
				break;

			case "childId":
				label = I18n.t("label_subtask");
				// 判断：如果新值不为空且非空字符串，添加#前缀
				if (StringUtils.isNotEmpty(detail.getValue())) {
					value = "#" + detail.getValue();
				}
				// 判断：如果旧值不为空且非空字符串，添加#前缀
				if (StringUtils.isNotEmpty(detail.getOldValue())) {
					oldValue = "#" + detail.getOldValue();
				}
				multiple = true;
				break;

			case "isPrivate":
				// 判断：如果新值不为空且非空字符串，根据值显示是/否
				if (StringUtils.isNotEmpty(detail.getValue())) {
					value = I18n.t(detail.getValue().equals("0") ? "general_text_No" : "general_text_Yes");
				}
				// 判断：如果旧值不为空且非空字符串，根据值显示是/否
				if (StringUtils.isNotEmpty(detail.getOldValue())) {
					oldValue = I18n.t(detail.getOldValue().equals("0") ? "general_text_No" : "general_text_Yes");
				}
				break;

			case "description":
				showDiff = true;
				break;
			}
			break;
		}
		case "attachment": {
			if (StringUtils.isNotEmpty(value)) {
				Long attachmentid = Long.parseLong(value);
				Attachment attachment = attachmentService.selectAttachmentById(attachmentid);
				if (attachment != null) {
					value = attachment.getFilename();
				}
			}
			break;
		}
		case "relation": {
			// 处理关联关系类型
			if (StringUtils.isNotEmpty(value)) {
				Long issueId = Long.parseLong(value);
				Issue issue = issueMapper.selectIssuesById(issueId);
				if (issue != null) {
					Tracker tracker = trackerMap.get(issue.getTrackerId());
					value = "<a href=\"javascript:void(0)\" onclick=\"openIssueTab(" + issue.getId() + ")\">"
							+ (tracker != null ? tracker.getName() : "") + " #" + issue.getId() + "</a>" + " "
							+ issue.getSubject();
				}
			}
			// 判断：如果旧值不为空且非空字符串，根据值显示是/否
			if (StringUtils.isNotEmpty(detail.getOldValue())) {
				Long issueId = Long.parseLong(detail.getOldValue());
				Issue issue = issueMapper.selectIssuesById(issueId);
				if (issue != null) {
					Tracker tracker = trackerMap.get(issue.getTrackerId());
					oldValue = "<a href=\"javascript:void(0)\" onclick=\"openIssueTab(" + issue.getId() + ")\">"
							+ (tracker != null ? tracker.getName() : "") + " #" + issue.getId() + "</a>" + " "
							+ issue.getSubject();
				}
			}
			break;
		}
		}

		if (noDetails) {
			return I18n.t("text_journal_changed_no_detail", Map.of("label", label));
		} else if (showDiff) {
			String s = I18n.t("text_journal_changed_no_detail", Map.of("label", label));
			return s;
		} else if (StringUtils.isNotEmpty(detail.getValue()) && StringUtils.isNotEmpty(value)) {
			// 判断：如果新值不为空，根据属性类型返回相应文本
			switch (detail.getProperty()) {
			case "attr":
			case "cf":
				// 判断：如果旧值不为空，返回修改文本
				if (StringUtils.isNotEmpty(detail.getOldValue()) && StringUtils.isNotEmpty(oldValue)
						&& !"null".equals(detail.getOldValue())) {
					return I18n.t("text_journal_changed", Map.of("label", label, "old", oldValue, "new", value));
				} else if (multiple) {
					return I18n.t("text_journal_added", Map.of("label", label, "value", value));
				} else {
					return I18n.t("text_journal_set_to", Map.of("label", label, "value", value));
				}
			case "attachment":
			case "relation":
				return I18n.t("text_journal_added", Map.of("label", label, "value", value));
			}
		} else {
			return I18n.t("text_journal_deleted", Map.of("label", label, "old", oldValue));
		}

		return "";
	}

	private String findNameByReflection(String field, String value) {
		if (StringUtils.isEmpty(value)) {
			return null;
		}
		if ("0".equals(value)) {
			return "";
		}

		try {
			Long id = Long.parseLong(value);

			Map<Long, Project> projectMap = commonService.getProjectMap();
			Map<Long, Tracker> trackerMap = commonService.getTrackerMap();
			Map<Long, IssueStatus> issueStatusMap = commonService.getIssueStatusMap();
			Map<Long, IssuePrioritie> issuePrioritieMap = commonService.getIssuePrioritieMap();
			Map<Long, IssueCategorie> issueCategorieMap = commonService.getIssueCategorieMap();

			switch (field) {
			case "projectId":
				// 查询项目名称
				Project project = projectMap.get(id);
				return project != null ? project.getName() : value;

			case "trackerId":
				// 查询跟踪器名称
				Tracker tracker = trackerMap.get(id);
				return tracker != null ? tracker.getName() : value;

			case "statusId":
				// 查询状态名称
				IssueStatus status = issueStatusMap.get(id);
				return status != null ? status.getName() : value;

			case "priorityId":
				// 查询优先级名称 - 需要检查是否有优先级Service
				try {
					// 假设优先级也使用IssueStatusService或专门的优先级Service
					IssuePrioritie priority = issuePrioritieMap.get(id);
					return priority != null ? priority.getName() : value;
				} catch (Exception e) {
					return value;
				}

			case "assignedToId":
				// 查询用户名称
				User user = userService.selectUserById(id);
				return user != null ? user.getUserName() : value;

			case "categoryId":
				// 查询类别名称
				try {
					IssueCategorie category = issueCategorieMap.get(id);
					return category != null ? category.getName() : value;
				} catch (Exception e) {
					return value;
				}

			case "startDate":
				// 日期字段直接返回原始值
				return value;

			default:
				return value;
			}
		} catch (NumberFormatException e) {
			// 如果value不是数字，直接返回原始值
			return value;
		}
	}

	@Override
	public JournalDetail queryByIssueIdAndPropKey(Long issueId, String propKey, Long authorId) {
		String jopropKeyedType = "Issue";
		return journalDetailMapper.queryByIssueIdAndPropKey(issueId, jopropKeyedType, propKey, authorId);
	}

	@Override
	public void createRelationDetails(Long journalId, IssueRelation issueRelation) {
		// 获取关联类型的中文描述
		String relationTypeDesc = IssueRelationType.getDescriptionByCode(issueRelation.getRelationType());

		// 创建关联关系的JournalDetail记录
		JournalDetail detail = new JournalDetail();
		detail.setJournalId(journalId);
		detail.setProperty("relation");
		detail.setPropKey(issueRelation.getRelationType());
		detail.setDescription(relationTypeDesc);
		detail.setOldValue("");
		detail.setValue(String.valueOf(issueRelation.getIssueToId()));

		// 插入JournalDetail记录
		journalDetailMapper.insertJournalDetails(detail);
	}

	@Override
	public void createDeleteRelationDetails(Long journalId, IssueRelation issueRelation) {
		// 获取关联类型的中文描述
		String relationTypeDesc = IssueRelationType.getDescriptionByCode(issueRelation.getRelationType());

		// 创建删除关联关系的JournalDetail记录
		JournalDetail detail = new JournalDetail();
		detail.setJournalId(journalId);
		detail.setProperty("relation");
		detail.setPropKey(issueRelation.getRelationType());
		detail.setDescription(relationTypeDesc);
		detail.setOldValue(String.valueOf(issueRelation.getIssueToId()));
		detail.setValue("");

		// 插入JournalDetail记录
		journalDetailMapper.insertJournalDetails(detail);
	}

}
